package org.hackystat.devcathlon.user;

import java.util.HashMap;
import java.util.Map;

/**
 * A thread-safe singleton class that manages access to the Teams in this system. 
 * @author Philip Johnson
 */
public class UserManager {
  /** The singleton instance. */
  private static UserManager theInstance = new UserManager();
  /** The (user name, user instance) tuples. */
  private Map<String, User> emails2users = new HashMap<String, User>();
  /** The private constructor. */
  private UserManager() {
    // does nothing at this point; will initialize from database later.
  }

  /**
   * Returns the singleton instance of the UserManager.
   * @return The UserManager.
   */
  public static UserManager getInstance() {
    return UserManager.theInstance;
  }

  /**
   * Adds a new user to the system. 
   * @param firstName The first name of the user. 
   * @param lastName The last name of the user. 
   * @param email The user's email (and Hackystat account).
   * @param password The Hackystat password. 
   * @return The new User instance, if successful.
   * @throws UserException If problems occur creating the user. 
   */
  public synchronized User addUser(String firstName, String lastName, String email, String password)
  throws UserException {
    if (this.emails2users.containsKey(email)) {
      throw new UserException("Attempt to add User with duplicate email: " + email);
    }
    // Probably should check to see that the user is registered with Hackystat? 
    User user = new User(firstName, lastName, email, password);
    this.emails2users.put(email, user);
    return user;
  }
  
  /**
   * Returns the User instance associated with the email, or null if not found. 
   * @param email The email of the User of interest. 
   * @return The User instance, or null if not found. 
   */
  public synchronized User getUser(String email) {
    return this.emails2users.get(email);
  }
  
  /**
   * Removes the specified user from the map of users. 
   * Does nothing if this user is not currently on the map.
   * @param email The email of the user to remove. 
   */
  public synchronized void deleteUser (String email) {
    this.emails2users.remove(email);
  }
}
